//
//  AppDelegate.m
//  ViewSwapper
//
//  Created by Russell Newlands on 14/02/2012.
//  Copyright (c) 2012 Jominy Research. All rights reserved.
//

#import "AppDelegate.h"
#import "PupilDetailViewController.h"
#import "Constants.h"
#import "JOSplitViewDelegate.h"

@interface AppDelegate ()

- (void)swapPlaceholderWithViewFromController:(NSViewController *)controller;

	@property (nonatomic, readonly) PupilDetailViewController *pupilDetailViewController;

@end

#pragma mark -

@implementation AppDelegate

@synthesize window = _window;

@synthesize outlineViewPlaceholder = _outlineViewPlaceholder;
@synthesize firstVertSV = _firstVertSV;
@synthesize horizontalSV = _horizontalSV; 
@synthesize pupilDetailViewPlaceholder = _pupilDetailViewPlaceholder;

@synthesize pupilDetailViewController = _pupilDetailViewController;

@synthesize persistentStoreCoordinator = __persistentStoreCoordinator; 
@synthesize managedObjectModel = __managedObjectModel;
@synthesize managedObjectContext = __managedObjectContext;



- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    [self swapPlaceholderWithViewFromController:[self pupilDetailViewController]];
	
	firstVertSVDelegate = [[JOSplitViewDelegate alloc] init];
	
	[firstVertSVDelegate setMinimumLength:kFirstVerticalSplitViewLeftMinWidth forViewAtIndex:kFirstVerticalSplitViewLeftIndex];	
    [firstVertSVDelegate setCanResize:kFirstVerticalSplitViewLeftCanResize forViewAtIndex:kFirstVerticalSplitViewLeftIndex];
	[firstVertSVDelegate setMinimumLength:kFirstVerticalSplitViewRightMinWidth forViewAtIndex:kFirstVerticalSplitViewRightIndex];
    [firstVertSVDelegate setCanResize:kFirstVerticalSplitViewRightCanResize forViewAtIndex:kFirstVerticalSplitViewRightIndex];
	
	[_firstVertSV setDelegate:firstVertSVDelegate];	
}

- (void)awakeFromNib
{
//    NSView *windowContentView = [_window contentView];
//    NSDictionary *views = NSDictionaryOfVariableBindings(_horizontalSV);
//    [_horizontalSV removeConstraints:[_horizontalSV constraints]];
//    [windowContentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_horizontalSV(>=400)]|" options:0 metrics:nil views:views]];
}

/**
    Returns the directory the application uses to store the Core Data store file. This code uses a directory named "ViewSwapper" in the user's Library directory.
 */
- (NSURL *)applicationFilesDirectory {

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *libraryURL = [[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
    return [libraryURL URLByAppendingPathComponent:@"ViewSwapper"];
}

/**
    Creates if necessary and returns the managed object model for the application.
 */
- (NSManagedObjectModel *)managedObjectModel {
    if (__managedObjectModel) {
        return __managedObjectModel;
    }
	
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"ViewSwapper" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
    return __managedObjectModel;
}

/**
    Returns the persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.)
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (__persistentStoreCoordinator) {
        return __persistentStoreCoordinator;
    }

    NSManagedObjectModel *mom = [self managedObjectModel];
    if (!mom) {
        NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));
        return nil;
    }

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
    NSError *error = nil;
    
    NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:[NSArray arrayWithObject:NSURLIsDirectoryKey] error:&error];
        
    if (!properties) {
        BOOL ok = NO;
        if ([error code] == NSFileReadNoSuchFileError) {
            ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error];
        }
        if (!ok) {
            [[NSApplication sharedApplication] presentError:error];
            return nil;
        }
    }
    else {
        if ([[properties objectForKey:NSURLIsDirectoryKey] boolValue] != YES) {
            // Customize and localize this error.
            NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]]; 
            
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            [dict setValue:failureDescription forKey:NSLocalizedDescriptionKey];
            error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict];
            
            [[NSApplication sharedApplication] presentError:error];
            return nil;
        }
    }
    
    NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"ViewSwapper.storedata"];
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
    if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]) {
        [[NSApplication sharedApplication] presentError:error];
        return nil;
    }
    __persistentStoreCoordinator = coordinator;

    return __persistentStoreCoordinator;
}

/**
    Returns the managed object context for the application (which is already
    bound to the persistent store coordinator for the application.) 
 */
- (NSManagedObjectContext *)managedObjectContext {
    if (__managedObjectContext) {
        return __managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        [dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey];
        [dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey];
        NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        [[NSApplication sharedApplication] presentError:error];
        return nil;
    }
    __managedObjectContext = [[NSManagedObjectContext alloc] init];
    [__managedObjectContext setPersistentStoreCoordinator:coordinator];

    return __managedObjectContext;
}

/**
    Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application.
 */
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window {
    return [[self managedObjectContext] undoManager];
}

/**
    Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user.
 */
- (IBAction)saveAction:(id)sender {
    NSError *error = nil;
    
    if (![[self managedObjectContext] commitEditing]) {
        NSLog(@"%@:%@ unable to commit editing before saving", [self class], NSStringFromSelector(_cmd));
    }

    if (![[self managedObjectContext] save:&error]) {
        [[NSApplication sharedApplication] presentError:error];
    }
}

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {

    // Save changes in the application's managed object context before the application terminates.

    if (!__managedObjectContext) {
        return NSTerminateNow;
    }

    if (![[self managedObjectContext] commitEditing]) {
        NSLog(@"%@:%@ unable to commit editing to terminate", [self class], NSStringFromSelector(_cmd));
        return NSTerminateCancel;
    }

    if (![[self managedObjectContext] hasChanges]) {
        return NSTerminateNow;
    }

    NSError *error = nil;
    if (![[self managedObjectContext] save:&error]) {

        // Customize this code block to include application-specific recovery steps.              
        BOOL result = [sender presentError:error];
        if (result) {
            return NSTerminateCancel;
        }

        NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message");
        NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info");
        NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title");
        NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title");
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:question];
        [alert setInformativeText:info];
        [alert addButtonWithTitle:quitButton];
        [alert addButtonWithTitle:cancelButton];

        NSInteger answer = [alert runModal];
        
        if (answer == NSAlertAlternateReturn) {
            return NSTerminateCancel;
        }
    }

    return NSTerminateNow;
}

#pragma mark -
#pragma mark My stuff


- (void)windowDidResize:(NSNotification *)notification
{    
    // NSRect hSViewRect = [_horizontalSV bounds];
    //  NSSize hSViewSize = hSViewRect.size;
    //  float hSViewWidth = hSViewSize.width;
    //  float hSViewHeight = hSViewSize.height;
    //  
    //  CGFloat minHorizontalSVWidth = 500;
    //  CGFloat minVerticalSVWidth = 300;
    //  NSSize newSize;
    //  
    //  if(hSViewWidth <= minHorizontalSVWidth) {
    //      CGFloat newWidth = [_outlineViewPlaceholder bounds].size.width + [_mainVerticalSV dividerThickness] + minHorizontalSVWidth;
    //      CGFloat newHeight = [_window minSize].height;
    //      newSize.width=newWidth;
    //      newSize.height=newHeight;
    //      
    //      [_window setMinSize:newSize];
    //  }
    //  
    //  if(hSViewHeight <= minVerticalSVWidth) {
    //      CGFloat newHeight = [_horizontalSV dividerThickness] + minVerticalSVWidth;
    //      CGFloat newWidth = [_window minSize].width;
    //      newSize.width=newWidth;
    //      newSize.height=newHeight;
    //      
    //      [_window setMinSize:newSize];
    //  }
 }


- (void)swapPlaceholderWithViewFromController:(NSViewController *)controller;
{
    
//    NSView *pupilDetailViewPlaceholder = [self pupilDetailViewPlaceholder];
//
//	NSView *realView = [controller view];
//	NSDictionary *views = NSDictionaryOfVariableBindings(realView);
//	
//	// Remove current subviews.
//	while ([[pupilDetailViewPlaceholder subviews] count] > 0) {
//		[[[pupilDetailViewPlaceholder subviews] lastObject] removeFromSuperview];
//	}
//	
//	// Disable autoresize masks translation on the real view otherwise auto-layout won't work! Then add it to placeholder.
//	[pupilDetailViewPlaceholder addSubview:realView];
//    [realView setTranslatesAutoresizingMaskIntoConstraints:NO];
//	
//	// Setup constraints after adding view to placeholder - we fit real view completely inside placeholder and make it resize with it. Note how we set contraints on the superview of the view which we want to layout!
//    
//	[pupilDetailViewPlaceholder addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[realView(>=190)]|" options:0 metrics:nil views:views]];
//	[pupilDetailViewPlaceholder addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[realView(>=100)]|" options:0 metrics:nil views:views]];
}


- (PupilDetailViewController *)pupilDetailViewController {
	
    if (_pupilDetailViewController)
        return _pupilDetailViewController;
	
	_pupilDetailViewController = [PupilDetailViewController viewControllerWithDefaultNib];
	return _pupilDetailViewController;
}


@end
